package com.ay.redisqps.service;

import com.ay.redisqps.dao.TicketRepository;
import com.ay.redisqps.pojo.Ticket;
import com.ay.redisqps.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/* *
 * Created by Ay on 2018/11/13
 */
@Service
public class TicketService3 {

    @Autowired
    TicketRepository ticketRepository;
    //标记该车次是否有人在重构缓存
    ConcurrentHashMap<String,String> mapLock = new ConcurrentHashMap<>();

    @Autowired
    RedisUtil redis;
    public Integer findTicketByName(String name){
        //1.先从缓存获取
        String value = redis.get(name);
        if(value != null){
            System.out.println(Thread.currentThread().getId()+"从缓存获取："+value);
            return Integer.valueOf(value);
        }
        boolean lock = false;
        try {
            /* putIfAbsent 如果不存在，添加键值，返回null，存在则返回存在的值 */
            lock = mapLock.putIfAbsent(name,"true") == null ;  //1000个请求，只有一个拿到锁，剩余人缓存降级
            if(lock){   //拿到锁
                //2.查询数据库
                Ticket ticket = ticketRepository.findByName(name);
                System.out.println(Thread.currentThread().getId()+"从数据库获取："+ticket.getTickets());
                //3.放入缓存
                redis.set(name,ticket.getTickets(),120);
                //4.有备份缓存 双写缓存 不设时间
            }else{
                //方案1 返回固定值
                System.out.println(Thread.currentThread().getId()+"固定值获取：0");
                return 0;
                //方案2 备份缓存
                //方案3 提示用户重试
            }
        }finally {
            if(lock){//有锁才释放
                mapLock.remove(name);//释放锁
            }

        }

        return 0;
    }
}
